Skip to content

Conversation

@Akaryatrh
Copy link
Contributor

@Akaryatrh Akaryatrh commented Aug 25, 2025

Adds OneKey keyring based on OneKey libraries.


Note

Adds OneKey hardware wallet support to the monorepo via a new keyring package.

  • New @metamask/eth-onekey-keyring package with OneKeyKeyring and OneKeyWebBridge using @onekeyfe/hd-web-sdk to handle PIN/passphrase UI, passphrase state, and transport switching
  • Implements unlock via xpub, HD path handling (default/BIP44/legacy), account pagination, and signing flows: transactions (incl. EIP-1559), personal messages, and EIP-712 typed data with address verification
  • Extensive Jest test suites for keyring and bridge, plus package configs (jest, tsconfig, typedoc), changelog, license, and README; updates root README, tsconfig references, and yarn.lock to include the new package

Written by Cursor Bugbot for commit 2d9d5c0. This will update automatically on new commits. Configure here.

@Akaryatrh Akaryatrh requested a review from a team as a code owner August 25, 2025 13:44
@socket-security
Copy link

socket-security bot commented Aug 25, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​onekeyfe/​hd-shared@​1.1.17-patch.1821007298100
Added@​types/​bytebuffer@​5.0.491001007480100
Added@​onekeyfe/​hd-transport@​1.1.17-patch.1841008398100
Added@​onekeyfe/​hd-web-sdk@​1.1.17-patch.1851008698100
Added@​onekeyfe/​hd-core@​1.1.17-patch.1851008598100

View full report

@Akaryatrh Akaryatrh force-pushed the feat/onekey-keyring branch from 2dc83be to a18c779 Compare August 25, 2025 13:46
@Akaryatrh Akaryatrh added the team-hardware-wallets This should be handled by the Hardware Wallets Team label Aug 25, 2025
@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

cursor[bot]

This comment was marked as outdated.

@github-actions
Copy link

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-api": "0.9.0-a18c779",
  "@metamask-previews/keyring-api": "20.1.0-a18c779",
  "@metamask-previews/eth-hd-keyring": "12.1.0-a18c779",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.2-a18c779",
  "@metamask-previews/eth-onekey-keyring": "0.1.0-a18c779",
  "@metamask-previews/eth-qr-keyring": "0.0.0-a18c779",
  "@metamask-previews/eth-simple-keyring": "10.0.0-a18c779",
  "@metamask-previews/eth-trezor-keyring": "9.0.0-a18c779",
  "@metamask-previews/keyring-internal-api": "8.1.0-a18c779",
  "@metamask-previews/keyring-internal-snap-client": "6.0.0-a18c779",
  "@metamask-previews/eth-snap-keyring": "16.1.0-a18c779",
  "@metamask-previews/keyring-snap-client": "7.0.0-a18c779",
  "@metamask-previews/keyring-snap-sdk": "6.0.0-a18c779",
  "@metamask-previews/keyring-utils": "3.1.0-a18c779"
}

@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

@github-actions
Copy link

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-api": "0.9.0-a621908",
  "@metamask-previews/keyring-api": "20.1.0-a621908",
  "@metamask-previews/eth-hd-keyring": "12.1.0-a621908",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.2-a621908",
  "@metamask-previews/eth-onekey-keyring": "0.1.0-a621908",
  "@metamask-previews/eth-qr-keyring": "0.0.0-a621908",
  "@metamask-previews/eth-simple-keyring": "10.0.0-a621908",
  "@metamask-previews/eth-trezor-keyring": "9.0.0-a621908",
  "@metamask-previews/keyring-internal-api": "8.1.0-a621908",
  "@metamask-previews/keyring-internal-snap-client": "6.0.0-a621908",
  "@metamask-previews/eth-snap-keyring": "16.1.0-a621908",
  "@metamask-previews/keyring-snap-client": "7.0.0-a621908",
  "@metamask-previews/keyring-snap-sdk": "6.0.0-a621908",
  "@metamask-previews/keyring-utils": "3.1.0-a621908"
}

cursor[bot]

This comment was marked as outdated.

@Akaryatrh Akaryatrh mentioned this pull request Aug 26, 2025
@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

@github-actions
Copy link

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-api": "0.9.0-3e52ac6",
  "@metamask-previews/keyring-api": "20.1.0-3e52ac6",
  "@metamask-previews/eth-hd-keyring": "12.1.0-3e52ac6",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.2-3e52ac6",
  "@metamask-previews/eth-onekey-keyring": "0.1.0-3e52ac6",
  "@metamask-previews/eth-qr-keyring": "0.0.0-3e52ac6",
  "@metamask-previews/eth-simple-keyring": "10.0.0-3e52ac6",
  "@metamask-previews/eth-trezor-keyring": "9.0.0-3e52ac6",
  "@metamask-previews/keyring-internal-api": "8.1.0-3e52ac6",
  "@metamask-previews/keyring-internal-snap-client": "6.0.0-3e52ac6",
  "@metamask-previews/eth-snap-keyring": "16.1.0-3e52ac6",
  "@metamask-previews/keyring-snap-client": "7.0.0-3e52ac6",
  "@metamask-previews/keyring-snap-sdk": "6.0.0-3e52ac6",
  "@metamask-previews/keyring-utils": "3.1.0-3e52ac6"
}

@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

2 similar comments
@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

@github-actions
Copy link

github-actions bot commented Sep 4, 2025

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-api": "0.9.0-a4bb524",
  "@metamask-previews/keyring-api": "20.1.0-a4bb524",
  "@metamask-previews/eth-hd-keyring": "12.1.0-a4bb524",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.2-a4bb524",
  "@metamask-previews/eth-onekey-keyring": "0.1.0-a4bb524",
  "@metamask-previews/eth-qr-keyring": "0.0.0-a4bb524",
  "@metamask-previews/eth-simple-keyring": "10.0.0-a4bb524",
  "@metamask-previews/eth-trezor-keyring": "9.0.0-a4bb524",
  "@metamask-previews/keyring-internal-api": "8.1.0-a4bb524",
  "@metamask-previews/keyring-internal-snap-client": "6.0.0-a4bb524",
  "@metamask-previews/eth-snap-keyring": "16.1.0-a4bb524",
  "@metamask-previews/keyring-snap-client": "7.0.0-a4bb524",
  "@metamask-previews/keyring-snap-sdk": "6.0.0-a4bb524",
  "@metamask-previews/keyring-utils": "3.1.0-a4bb524"
}

@github-actions
Copy link

github-actions bot commented Jan 8, 2026

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-api": "0.12.0-ca02a28",
  "@metamask-previews/keyring-api": "21.3.0-ca02a28",
  "@metamask-previews/eth-hd-keyring": "13.0.0-ca02a28",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.2-ca02a28",
  "@metamask-previews/eth-onekey-keyring": "0.1.0-ca02a28",
  "@metamask-previews/eth-qr-keyring": "1.1.0-ca02a28",
  "@metamask-previews/eth-simple-keyring": "11.0.0-ca02a28",
  "@metamask-previews/eth-trezor-keyring": "9.0.0-ca02a28",
  "@metamask-previews/keyring-internal-api": "9.1.1-ca02a28",
  "@metamask-previews/keyring-internal-snap-client": "8.0.1-ca02a28",
  "@metamask-previews/eth-snap-keyring": "18.0.2-ca02a28",
  "@metamask-previews/keyring-snap-client": "8.1.1-ca02a28",
  "@metamask-previews/keyring-snap-sdk": "7.1.1-ca02a28",
  "@metamask-previews/keyring-utils": "3.1.0-ca02a28"
}

@Akaryatrh Akaryatrh force-pushed the feat/onekey-keyring branch from ca02a28 to 89518ee Compare January 9, 2026 10:23
@Akaryatrh
Copy link
Contributor Author

@SocketSecurity ignore npm/async-function

@Akaryatrh Akaryatrh force-pushed the feat/onekey-keyring branch from 89518ee to ca5bb42 Compare January 9, 2026 10:28
@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

@github-actions
Copy link

github-actions bot commented Jan 9, 2026

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-api": "0.12.0-ca5bb42",
  "@metamask-previews/keyring-api": "21.3.0-ca5bb42",
  "@metamask-previews/eth-hd-keyring": "13.0.0-ca5bb42",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.2-ca5bb42",
  "@metamask-previews/eth-onekey-keyring": "0.1.0-ca5bb42",
  "@metamask-previews/eth-qr-keyring": "1.1.0-ca5bb42",
  "@metamask-previews/eth-simple-keyring": "11.0.0-ca5bb42",
  "@metamask-previews/eth-trezor-keyring": "9.0.0-ca5bb42",
  "@metamask-previews/keyring-internal-api": "9.1.1-ca5bb42",
  "@metamask-previews/keyring-internal-snap-client": "8.0.1-ca5bb42",
  "@metamask-previews/eth-snap-keyring": "18.0.2-ca5bb42",
  "@metamask-previews/keyring-snap-client": "8.1.1-ca5bb42",
  "@metamask-previews/keyring-snap-sdk": "7.1.1-ca5bb42",
  "@metamask-previews/keyring-utils": "3.1.0-ca5bb42"
}

reject(new Error('signature doesnt match the right address'));
}
// eslint-disable-next-line promise/no-multiple-resolved
resolve(signature);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing return after reject causes double promise resolution

Medium Severity

In signPersonalMessage, when the recovered signature address doesn't match the expected account, reject() is called but execution continues and resolve(signature) is also invoked. The eslint-disable-next-line promise/no-multiple-resolved comment confirms this was caught by the linter but suppressed rather than fixed. While Promise semantics mean the rejection wins, calling both reject and resolve on the same promise is incorrect behavior and could lead to confusion or bugs if the code is modified later. A return statement is needed after the reject() call.

Fix in Cursor Fix in Web

#onUIEvent?: ((event: Unsuccessful['payload']) => void) | undefined;

#handleBlockErrorEvent(payload: Unsuccessful): void {
const { code } = payload.payload;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing null check causes crash in error handler

Medium Severity

The #handleBlockErrorEvent method immediately destructures payload.payload without a null check, but callers pass result after checking result?.success with optional chaining. This inconsistency means if an SDK method returns null or undefined, the optional chaining check passes (since undefined?.success is falsy), but then #handleBlockErrorEvent(result) crashes with a TypeError when accessing undefined.payload. The pattern repeats in getPublicKey, getPassphraseState, ethereumSignTransaction, ethereumSignMessage, and ethereumSignTypedData.

Additional Locations (2)

Fix in Cursor Fix in Web

@Akaryatrh
Copy link
Contributor Author

@SocketSecurity ignore npm/async-function@1.0.0

reject(new Error('signature doesnt match the right address'));
}
// eslint-disable-next-line promise/no-multiple-resolved
resolve(signature);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing return after reject causes multiple promise settlements

Medium Severity

In signPersonalMessage, when the recovered address doesn't match the expected address, reject() is called but execution continues and resolve(signature) is also called. The eslint-disable comment for promise/no-multiple-resolved acknowledges this issue but masks it rather than fixing it. A return statement is needed after the reject() call to prevent the promise from being settled twice and to avoid returning an invalid signature path.

Fix in Cursor Fix in Web

},
});
}
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UI_EVENT subscription never removed causes memory leak

Medium Severity

The UI_EVENT event listener added via this.sdk?.on('UI_EVENT', ...) in init() is never unsubscribed. Neither destroy() nor dispose() removes this listener before clearing the SDK reference. The callback closure holds references to this (the bridge instance), causing memory to accumulate if the bridge is initialized and destroyed multiple times during the application lifecycle.

Additional Locations (1)

Fix in Cursor Fix in Web

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

async dispose(): Promise<void> {
this.sdk?.dispose();
return Promise.resolve();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dispose() doesn't reset state preventing SDK re-initialization

Medium Severity

The dispose() method calls sdk.dispose() but doesn't reset isSDKInitialized or sdk. Since OneKeyKeyring.destroy() calls bridge.dispose() (not bridge.destroy()), the bridge is left in an inconsistent state where isSDKInitialized remains true but the SDK is disposed. Subsequent calls to init() return early without re-initializing, and SDK method calls will fail on the disposed SDK.

Additional Locations (1)

Fix in Cursor Fix in Web

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

@github-actions
Copy link

github-actions bot commented Jan 9, 2026

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-api": "0.12.0-e40d1ad",
  "@metamask-previews/keyring-api": "21.3.0-e40d1ad",
  "@metamask-previews/eth-hd-keyring": "13.0.0-e40d1ad",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.2-e40d1ad",
  "@metamask-previews/eth-onekey-keyring": "0.1.0-e40d1ad",
  "@metamask-previews/eth-qr-keyring": "1.1.0-e40d1ad",
  "@metamask-previews/eth-simple-keyring": "11.0.0-e40d1ad",
  "@metamask-previews/eth-trezor-keyring": "9.0.0-e40d1ad",
  "@metamask-previews/keyring-internal-api": "9.1.1-e40d1ad",
  "@metamask-previews/keyring-internal-snap-client": "8.0.1-e40d1ad",
  "@metamask-previews/eth-snap-keyring": "18.0.2-e40d1ad",
  "@metamask-previews/keyring-snap-client": "8.1.1-e40d1ad",
  "@metamask-previews/keyring-snap-sdk": "7.1.1-e40d1ad",
  "@metamask-previews/keyring-utils": "3.1.0-e40d1ad"
}

@Akaryatrh Akaryatrh force-pushed the feat/onekey-keyring branch from e40d1ad to 15bb912 Compare January 16, 2026 10:05
cursor[bot]

This comment was marked as outdated.

@Akaryatrh Akaryatrh force-pushed the feat/onekey-keyring branch from 15bb912 to acd41b7 Compare January 21, 2026 09:39
@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

cursor[bot]

This comment was marked as outdated.

@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

cursor[bot]

This comment was marked as outdated.

@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

1 similar comment
@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

@github-actions
Copy link

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-api": "0.12.0-feb98c5",
  "@metamask-previews/hw-wallet-sdk": "0.2.0-feb98c5",
  "@metamask-previews/keyring-api": "21.3.0-feb98c5",
  "@metamask-previews/eth-hd-keyring": "13.0.0-feb98c5",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.2-feb98c5",
  "@metamask-previews/eth-onekey-keyring": "0.1.0-feb98c5",
  "@metamask-previews/eth-qr-keyring": "1.1.0-feb98c5",
  "@metamask-previews/eth-simple-keyring": "11.0.0-feb98c5",
  "@metamask-previews/eth-trezor-keyring": "9.0.0-feb98c5",
  "@metamask-previews/keyring-internal-api": "9.1.1-feb98c5",
  "@metamask-previews/keyring-internal-snap-client": "8.0.1-feb98c5",
  "@metamask-previews/eth-snap-keyring": "18.0.2-feb98c5",
  "@metamask-previews/keyring-snap-client": "8.1.1-feb98c5",
  "@metamask-previews/keyring-snap-sdk": "7.1.1-feb98c5",
  "@metamask-previews/keyring-utils": "3.1.0-feb98c5"
}

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.


return this.hdPath === newHdPath;
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing lock() method causes test runtime failure

High Severity

The OneKeyKeyring class is missing a lock() method, but the test file explicitly calls keyring.lock() and expects isUnlocked() to return false afterward. Since isUnlocked() returns Boolean(this.hdk?.publicKey), a lock() method that resets the HDKey is needed for the feature to work and for the test to pass. Without this method, the test will fail with a runtime error and the keyring cannot be locked programmatically.

Additional Locations (1)

Fix in Cursor Fix in Web

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@Akaryatrh Akaryatrh force-pushed the feat/onekey-keyring branch from feb98c5 to 2d9d5c0 Compare January 21, 2026 11:10
@Akaryatrh
Copy link
Contributor Author

@metamaskbot publish-preview

@github-actions
Copy link

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-api": "0.12.0-2d9d5c0",
  "@metamask-previews/hw-wallet-sdk": "0.2.0-2d9d5c0",
  "@metamask-previews/keyring-api": "21.3.0-2d9d5c0",
  "@metamask-previews/eth-hd-keyring": "13.0.0-2d9d5c0",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.2-2d9d5c0",
  "@metamask-previews/eth-onekey-keyring": "0.1.0-2d9d5c0",
  "@metamask-previews/eth-qr-keyring": "1.1.0-2d9d5c0",
  "@metamask-previews/eth-simple-keyring": "11.0.0-2d9d5c0",
  "@metamask-previews/eth-trezor-keyring": "9.0.0-2d9d5c0",
  "@metamask-previews/keyring-internal-api": "9.1.1-2d9d5c0",
  "@metamask-previews/keyring-internal-snap-client": "8.0.1-2d9d5c0",
  "@metamask-previews/eth-snap-keyring": "18.0.2-2d9d5c0",
  "@metamask-previews/keyring-snap-client": "8.1.1-2d9d5c0",
  "@metamask-previews/keyring-snap-sdk": "7.1.1-2d9d5c0",
  "@metamask-previews/keyring-utils": "3.1.0-2d9d5c0"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

team-hardware-wallets This should be handled by the Hardware Wallets Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants